home *** CD-ROM | disk | FTP | other *** search
/ Shareware Grab Bag / Shareware Grab Bag.iso / 014 / uasmls.arc / UASM.DOC < prev    next >
Encoding:
Text File  |  1985-09-02  |  25.5 KB  |  759 lines

  1.  
  2.                                                                           1
  3.  
  4.                                 UASM.DOC
  5.  
  6.           UASM  (for  Unassembler)  consists  of  five  files at this
  7.      time:  UASM.DOC, UASM-JMP.BAS,  UASM-INT.BAS,  UASM-STR.BAS  and
  8.      UASM-DOS.MAC,  with  the  purpose  of converting the unassembled
  9.      listing of a .COM file from DEBUG into a  .ASM  file  which  can
  10.      be modified and re-assembled with the Macro assembler.  
  11.  
  12.      **************************** NOTICE ****************************
  13.  
  14.         USER  SUPPORTED  SOFTWARE  (With  thanks to Andrew Flugelman)
  15.       
  16.      A limited license is granted to all  users  of  these  programs,
  17.      to  make  and  distribute  copies for other users subject to the
  18.      following conditions:                                 
  19.  
  20.           1.   None of the notices or credits  are  to  be  bypassed,
  21.                altered, or removed.
  22.           2.   The  programs  are  not  to be distributed in modified
  23.                form.  (Users  are  encouraged  to  distribute   MERGE
  24.                files.)
  25.           3.   No  fee  is  to be charged (or any other consideration
  26.                received) for copying  or  distributing  the  programs
  27.                without  an express written agreement with White Crane
  28.                Systems.                                 
  29.      ***************************************************************
  30.  
  31.                UASM - The White Crane Systems Unassembler 
  32.  
  33.           If you are using these program and finding  them  of  value
  34.      please  send  a  cash  contribution  to support their upkeep and
  35.      distribution.  Use the UASM system  of  programs  to  unassemble
  36.      one  average  length .COM file, look over the results and calcu-
  37.      late how many hours  this  would  have  taken  you  to  produce.
  38.      Multiply  this  by  the  minimum  wage,  contribute that amount,
  39.      and use the program free thereafter. If  that's  too  much  just
  40.      send  $20.   Supporters will receive free notice of enhancements
  41.      and updates. 
  42.           In any case you  are  encouraged  to  copy  and  distribute
  43.      UASM  to  your  friends  provided  you  do so free of charge and
  44.      in unmodified form. 
  45.       
  46.                              Guy C. Gordon 
  47.                           White Crane Systems 
  48.                           3194 Friar Tuck Way 
  49.                           Doraville, GA 30340 
  50.  
  51.  
  52.  
  53.  
  54.  
  55.  
  56.  
  57.  
  58.  
  59.  
  60.  
  61.  
  62.  
  63.  
  64.  
  65.  
  66.  
  67.  
  68.  
  69.  
  70.                                                                           2
  71.  
  72.                               INTRODUCTION
  73.  
  74.           The strategy used in this system is to capture  the  output
  75.      of  DEBUG  and  run  it through a series of BASIC programs, each
  76.      of which modifies one type of statement in the  listing,  making
  77.      it  more  like  an  .ASM  source  file.  This keeps each program
  78.      short and fast, and allows you to look over the output  at  each
  79.      step  to make sure no mistakes have been entered.  It also makes
  80.      the programs easy to understand and improve, as  new  steps  can
  81.      be  added  without  interfering  with  the first steps. Later in
  82.      its development UAand improve, as  new  steps  can
  83.      be  added  without  interfering  with  the first steps. Later in
  84.      its development UASM will combine  these  steps.   I  hope  that
  85.      users  of  these  programs  will  send  me their improvements so
  86.      that I may add them to future releases.  
  87.  
  88.           UASM-JMP takes captured unassembled code from DEBUG  (which
  89.      we  will  name  FILE.DB)  and  finds all addresses referenced by
  90.      the various Jump, Call, and Loop instructions.  These referenced
  91.      addresses  are  made  into  labels of the form Lhhhh (where hhhh
  92.      is the hex address).  A new  file  (FILE.JMP)  is  then  written
  93.      in  the  form  of  assembler  source code.  All of the addresses
  94.      and hex opcodes in the left two columns  of  the  DEBUG  listing
  95.      are  left  out.   Referenced  lines are appropriately labeled as
  96.      Lhhhh:.  
  97.  
  98.           UASM-INT reads FILE.JMP and writes  FILE.INT  in  which  it
  99.      has added Macro calls and comments explaining the various Inter-
  100.      rupts.  The macros, symbols, and  comments  are  read  from  the
  101.      file  UASM-DOS.MAC.  This file contains a table of EQUates which
  102.      define the symbols for the various DOS function  calls  and  the
  103.      DOSCALL  macro.   It  is  included  in  FILE.INT  by means of an
  104.      INCLUDE directive.
  105.  
  106.           UASM-STR reads FILE.INT  and  writes  FILE.STR,  attempting
  107.      to  find  all  strings  and variables used by FILE.COM.  When it
  108.      finds an address it reads the string or variable  from  FILE.COM
  109.      and generates the appropriate data statement (e.g. Dhhhh    DB
  110.           'string')  which  it appends to FILE.STR, and comments each
  111.      line of code which references that address.
  112.  
  113.           From that point on, you  must  take  over  and  supply  the
  114.      remaining  text  strings  and variables that are addressed.  You
  115.      should heavily comment the code as you go through it and  change
  116.      the  labels  that  UASM has assigned into more meaningful names.
  117.      This is best done with the global change command  in  your  text
  118.      editor.  I also recommend using the Macro CREF program to obtain
  119.      a cross reference map of the symbols.
  120.  
  121.           These programs are by no means  infallible,  and  they  can
  122.      no  more  read  the programmers' mind than you or I, so you will
  123.      have to check the output  closely.   If  you  expect  to  simply
  124.      run  UASM  and  be  handed  a usable source file you're going to
  125.      be disappointed.  On the other hand, if  you've  ever  tried  to
  126.  
  127.  
  128.  
  129.  
  130.  
  131.  
  132.  
  133.  
  134.  
  135.  
  136.  
  137.  
  138.  
  139.  
  140.                                                                           3
  141.  
  142.      understand  a  program  from  just  a  DEBUG listing you will be
  143.      pleasantly surprised.  UASM  will  aid  you  in  studying  other
  144.      programs  by  doing  a lot of the dirty work for you, but if you
  145.      don't study the code you won't get usable output.
  146.        
  147.           I have been using these programs  to  unassemble  DEBUG.COM
  148.      and  COMMAND.COM.   When  I  have  them sufficiently commented I
  149.      will post them on the BBS's.  It  is  my  hope  that  UASM  will
  150.      lead  to a whole library of well commented, "reverse engineered"
  151.      source code for  the  MS-DOS  operating  system  and  utilities.
  152.      I  would  appreciate  anyone  else working on the same to upload
  153.      your results to the BBS.  Suggestions and improvements  to  UASM
  154.      are  welcome.   I  may  be  contacted  through any of the IBM-PC
  155.      BBS's in Atlanta, or write: 
  156.  
  157.                      Guy C. Gordon
  158.                White Crane Systems
  159.                3194 Friar Tuck Way
  160.                Doraville, GA 30340
  161.  
  162.  
  163.  
  164.  
  165.  
  166.  
  167.  
  168.  
  169.  
  170.  
  171.  
  172.  
  173.  
  174.  
  175.  
  176.  
  177.  
  178.  
  179.  
  180.  
  181.  
  182.  
  183.  
  184.  
  185.  
  186.  
  187.  
  188.  
  189.  
  190.  
  191.  
  192.  
  193.  
  194.  
  195.  
  196.  
  197.  
  198.  
  199.  
  200.  
  201.  
  202.  
  203.  
  204.  
  205.  
  206.  
  207.  
  208.                                                                           4
  209.  
  210.                          OPERATING INSTRUCTIONS
  211.                                  -DEBUG-
  212.  
  213.           As an  example,  we  will  unassemble  a  fictitious  file,
  214.      FILE.COM
  215.      A>debug file.com
  216.      -r
  217.      .....CX=1780 ...         ;file length in hex bytes
  218.      -d 100 l 1780            ;display entire file
  219.  
  220.           In  the  listing  that  follows  you should be able to spot
  221.      ASCII text and any regular binary tables.  Write  down  the  be-
  222.      ginning  and  ending  addresses  of  these, as we do not want to
  223.      unassemble them, but we will  want  a  printed  copy.   Our  aim
  224.      is  to  put together a list of all blocks of code to be unassem-
  225.      bled and string addresses for UASM-STR.  Look at the code before
  226.      each  block  of  text.   Usually it will be preceded by a hex C3
  227.      which is a RET instruction, but there may be a JMP, JMPS,  IRET,
  228.      or  RETF instead.  This is the last instruction we want to unas-
  229.      semble in the block of  code  preceding  the  text.   Take  your
  230.      time  and  go  through  the  entire  file, unassembling code and
  231.      making sure that the output looks reasonable.  
  232.  
  233.           Reasonable code contains such things as CALL  or  Jump  in-
  234.      structions to nearby addresses, INT 21 instructions and multiple
  235.      operations on single registers.  It does not contain DB instruc-
  236.      tions  or  very many 00 bytes.  Also the ASCII display of a sec-
  237.      tion of code will look totally random,  with  about  50%  of  it
  238.      being  displayable  characters.   (The  rest  will  be periods.)
  239.       Peter Norton has given a good demonstration of this in  chapter
  240.      6  of  "Inside  the IBM-PC".  One warning--the DEBUG unassembler
  241.      tends to lock into phase with the correct code,  which  is  very
  242.      nice,  but  be  certain  that the beginning few instructions are
  243.      also in phase.  Sections of code that are in phase will  contain
  244.      Jumps  and  CALLs  to  other sections, thus telling you where to
  245.      start unassembling.
  246.  
  247.           At the end of this  investigation  of  the  .COM  file  you
  248.      should  have  a  list  of  the  starting and ending addresses of
  249.      all the code blocks and all the string blocks.   The  next  step
  250.      depends upon whether you have DOS 2.0 or not.  It is much easier
  251.      if you have 2.0, or can to  this  part  on  a  friend's  machine
  252.      who  has  it.   This  is  because  under DOS 2.0 we can pipe the
  253.      output of DEBUG into  a  file  thus  capturing  the  unassembled
  254.      code for input to UASM-JMP.  Under DOS version 1. we must modify
  255.      DEBUG (using DEBUG of course) to get it to  write  the  file  we
  256.      need.
  257.  
  258.  
  259.  
  260.  
  261.  
  262.  
  263.  
  264.  
  265.  
  266.  
  267.  
  268.  
  269.  
  270.  
  271.  
  272.  
  273.  
  274.  
  275.  
  276.                                                                           5
  277.  
  278.                         DEBUG - 2.0 Instructions
  279.  
  280.           Create  a  file, FILE.IN, with the following DEBUG instruc-
  281.      tions:
  282.  
  283.      u addr 1 addr 2               ;addresses of blocks of
  284.      u addr 3 addr 4               ; code to unassemble
  285.      u addr 5 addr 6               ; from our initial investigation
  286.      q                        ;Must have Quit instruction at end
  287.  
  288.           Now we can run DEBUG and pipe the output to a disk file.
  289.  
  290.      DEBUG FILE.COM <FILE.IN >FILE.DB
  291.  
  292.           FILE.DB is the input for UASM-JMP.
  293.  
  294.  
  295.  
  296.  
  297.                         DEBUG - 1.1 Instructions
  298.  
  299.          While it is quite easy to capture the output of DEBUG  under
  300.      DOS  2.0  since we can pipe it to a file, under earlier versions
  301.      of DOS we have no such option.  However, DEBUG is an exceptional-
  302.      ly powerful program, and already  contains  the  code  necessary
  303.      to  write  a disk file with the Write command.  We will use this
  304.      to capture the Unassembled code.  
  305.  
  306.           If we unassemble and examine DEBUG, we can find the follow-
  307.      ing subroutine:
  308.  
  309.      02C8:02C0 PUSH AX        ;save registers
  310.                PUSH DX
  311.                AND  AL,7F          ;insure character is ASCII
  312.                XCHG DX,AX          ;put character in DL
  313.                MOV  AH,02          ;DOS Function 2 to display DL
  314.                INT  21
  315.                POP  DX        ;restore registers
  316.                POP  AX
  317.                RET            ;return
  318.  
  319.           As  it  turns  out,  DEBUG  does  all screen output through
  320.      this subroutine.  Thus we can modify just  this  subroutine  and
  321.      capture  each  character  as  it  is displayed.  What we will do
  322.      with it is write it out to an unused portion  of  memory.   From
  323.      there  we  can  write  all  the output to a file using the Write
  324.      command.
  325.  
  326.  
  327.  
  328.  
  329.  
  330.  
  331.  
  332.  
  333.  
  334.  
  335.  
  336.  
  337.  
  338.  
  339.  
  340.  
  341.  
  342.  
  343.  
  344.                                                                           6
  345.  
  346.           Our subroutine to store character AL in consecutive  memory
  347.      locations  will be very small--about 20 bytes.  We'll need some-
  348.      place to put it.  For DEBUG 1.07 I chose  to  put  it  inside  a
  349.      string  which  is  only printed once--the message "DEBUG version
  350.      1.07" located at CS:0102.  Here is the subroutine:
  351.  
  352.      02C8:0102 DW   3300      ;pointer to memory
  353.                PUSH DI        ;save index register
  354.                SEG  CS        ;offset from code, not ES
  355.                MOV  DI,[0102] ;get pointer
  356.                SEG  CS        ;
  357.                STOSB          ;store char in AL into memory
  358.                SEG  CS        ;
  359.                MOV  [0102],DI ;store incremented pointer
  360.                POP  DI        ;restore register
  361.                XCHG DX,AX     ;complete the instructions that
  362.                MOV  AH,02     ; CALL to this routine replaced
  363.                RET            ;Return to Display routine
  364.  
  365.           We can store this  subroutine  over  the  string  with  the
  366.      Enter  command.  (here  02C8  is the base segment where DEBUG is
  367.      loaded on my system):
  368.  
  369.      E 2C8:102 00 33 57 2E 8B 3E 02 01 2E AA 2E 89 3E  02  01  5F  92
  370.                B4 02 C3
  371.  
  372.      We  can  check  that  this was entered correctly by Unassembling
  373.      it:
  374.  
  375.      U 2C8:104      ;you should see the subroutine listed above.
  376.  
  377.           The choice of memory location is up to you.   3300  Is  the
  378.      value  I  used  while  unassembling  DEBUG.  It should be larger
  379.      than the sum of the sizes (in bytes) of DEBUG  and  the  program
  380.      you  are  unassembling.   To  have  this  subroutine called each
  381.      time DEBUG writes a character, we insert a subroutine Call:
  382.  
  383.      E 2C8:2C4 E8 3D FE       ;Call 0104
  384.  
  385.      This puts a CALL 0104 in place of  XCHG  DX,AX  and  MOV  AH,02.
  386.      That  is  why  we  perform  those  instructions before returning
  387.      to the display routine.  The very next charter printed by  DEBUG
  388.      after  you  Enter  the  above command will be stored in location
  389.      2C8:3300 as well as displayed on the screen. 
  390.  
  391.  
  392.  
  393.  
  394.  
  395.  
  396.  
  397.  
  398.  
  399.  
  400.  
  401.  
  402.  
  403.  
  404.  
  405.  
  406.  
  407.  
  408.  
  409.  
  410.  
  411.  
  412.                                                                           7
  413.  
  414.           Immediately  after  entering  the  CALL  instruction  above
  415.      you  should  begin  the  Unassemble commands that you determined
  416.      will give you all the code for the program.  
  417.  
  418.      U 100 4D5
  419.      U 6b0 799
  420.      etc.
  421.      D 2C8:102 103  ;This displays the pointer to the end of text
  422.           B3 D9          ;This means we filled memory to D9B3
  423.                          ;(remember the 8088 stores words LSB first)
  424.      H D9B3 3300         ;Hex arithmetic
  425.           0CB3 A6B3      ;  D9B3 - 3300 = A6B3
  426.      R CX
  427.           CX=1748
  428.           :A6B3          ;load CX register with # of bytes to write
  429.      N FILE.DB           ;name the output file
  430.      W 2C8:3300          ;writing from 3300 off. from DEBUG base
  431.         Writing A6B3 bytes
  432.      E 2C8:102 00 33          ;reset pointer if out of space
  433.  
  434.           Remember, you can only write text to  memory  up  to  2C8:-
  435.      FFFF.   If you exceed that you will write over DEBUG at 2C8:0000
  436.      and will probably have to  re-boot.   If  FILE.COM  is  too  big
  437.      to  Unassemble  in  one  pass you'll have to do it in pieces and
  438.      append them together with your text  editor.   For  this  reason
  439.      it  is  a  good  idea  to  modify and save a copy of DEBUG under
  440.      another name such as UDEBUG.  If you need to perform  any  other
  441.      operations  with  a  modified DEBUG that you do not want written
  442.      to memory you can restore DEBUG to normal operation with:
  443.  
  444.      E 2C8:2C4 92 B4 02  ;restores XCHG DX,AX and MOV AH,02
  445.  
  446.          Now text edit FILE.DB and remove any extraneous  lines  such
  447.      as  debug  prompts  that  might  have  been displayed.  If there
  448.      are any TABs in FILE.DB  they  will  confuse  UASM-JMP  and  the
  449.      others.   DEBUG  1.1 appears to put a TAB after each instruction
  450.      while version 2.0 does not.  I always use  the  text  editor  to
  451.      change  all  TABs  to  the appropriate number of spaces.  (Users
  452.      of PMATE, use the YF command.)
  453.  
  454.           Any of the memory addresses above may vary with your operat-
  455.      ing system and DEBUG version.  The  values  given  are  for  the
  456.      Victor  9000,  MS-DOS  1.25a,  and DEBUG 1.07.  The Base Segment
  457.      where DEBUG is loaded (2C8 above) will depend upon your  machine
  458.      and  operating  system,  and  is  found by using DEBUG to Search
  459.      for itself in memory.  The display subroutine  (2C0  above)  de-
  460.      pends  upon  your  DEBUG  version  number.   The same subroutine
  461.      occurs at 2B5 in the DEBUG that  comes  with  PC-DOS  1.10,  and
  462.      will  appear near these locations in any other version 1 DEBUGs.
  463.      If you store the capture  subroutine  at  some  other  place  in
  464.      memory  you  need  to  change  the two [0102] references and the
  465.      CALL 0104 instruction.  
  466.  
  467.  
  468.  
  469.  
  470.  
  471.  
  472.  
  473.  
  474.  
  475.  
  476.  
  477.  
  478.  
  479.  
  480.                                                                           8
  481.  
  482.                          UASM-JMP  Instructions
  483.  
  484.            Run UASM-JMP as you would  any  basic  program.   It  will
  485.      prompt  you  for  the  name of input and output files.   Respond
  486.      with  FILE.DB ,which we created above, and B:FILE.JMP  for  out-
  487.      put.   If  file  extensions  are not provided, .DB and .JMP will
  488.      be assumed for input and output respectively.  Also  the  output
  489.      file  name  will default to the input file name. I highly recom-
  490.      mend putting these files on separate drives if  you  don't  have
  491.      a  fixed  disk  or  a  RAM disk.  This will speed up the program
  492.      and save wear on your floppies.
  493.  
  494.           UASM-JMP will make  two  passes  through  the  input  file.
  495.      On  the first pass it will build a list of all referenced lines.
  496.      It then sorts  this  list  (shell  sort),  eliminates  duplicate
  497.      references,  and on the second pass, labels all of the referenc-
  498.      es.  The output will be displayed on  your  screen  as  well  as
  499.      written out on the second pass.  
  500.  
  501.           If  the  program  finds  a  Jump  or CALL to an address not
  502.      contained in the file you will  get  the  message  "WARNING!  No
  503.      code  for  this  label".   This most likely means you missed the
  504.      block of code starting at address hhhh  and  will  have  to  add
  505.      it  to  FILE.DB.   The  statement after an unconditional program
  506.      transfer (JMP or RET) is always labeled.  The message  "WARNING!
  507.      This  label  not referenced" means that there is no Jump or CALL
  508.      to this label.  It might be an interrupt handler or, in a highly
  509.      modified  program,  it  might  be code left over from an earlier
  510.      version which is no  longer  executed.   (NOP  instructions  are
  511.      not  force  labeled, but the following instruction is.)  A large
  512.      number of these errors might indicate  that  they  are  accessed
  513.      by  an  address  table.   Both  of  the above errors might occur
  514.      if you miss a block of code, unassemble  a  data  area,  or  the
  515.      code modifies itself.
  516.  
  517.           For  added  readability,  UASM-JMP  inserts  one blank line
  518.      after each JMP or JMPS  instruction  and  three  lines  after  a
  519.      RET or IRET.  This helps separate Proceedures.
  520.  
  521.  
  522.  
  523.                          UASM-INT  Instructions
  524.  
  525.           To  run  UASM-INT  you  must  also have the data file UASM-
  526.      DOS.MAC on one of the drives.   UASM-INT  will  prompt  you  for
  527.      an input and output file names.  If extensions are not provided,
  528.      .JMP and .INT will be assumed for input and  output  respective-
  529.      ly.   The program then loads the symbol table contained in UASM-
  530.      DOS.MAC.   While reading  through  FILE.JMP,  whenever  UASM-INT
  531.      encounters  an  INT  instruction  it  adds a Macro call, Symbols
  532.      for the DOS function calls, and Comments,  all  from  the  UASM-
  533.      DOS.MAC  file.  These lines will also be displayed on the screen
  534.      as the program progresses.   Note  that  the  DOSCALL  Macro  is
  535.      inserted  in the text, but the INT instructions are not deleted.
  536.      After you have checked the code you  must  delete  the  INT  and
  537.      any MOV instructions that will be duplicated by the Macro.
  538.  
  539.  
  540.  
  541.  
  542.  
  543.  
  544.  
  545.  
  546.  
  547.  
  548.                                                                           9
  549.  
  550.                           UASM-STR Instructions
  551.  
  552.           To  run  UASM-STR  you  must  have the original FILE.COM or
  553.      other binary file on disk.  The  program  will  prompt  you  for
  554.      the  input,  output,  and binary file names.  These will default
  555.      to .INT, .STR and .COM if  no  other  extension  is  given.   As
  556.      usual,  the  input  file  name  will be used as a default if you
  557.      do not specify the others, and you should put  the  output  file
  558.      on a different floppy drive than the input file.  
  559.  
  560.           You  will  then  be  prompted for any string area addresses
  561.      that you may have found while  examining  FILE.COM  with  DEBUG.
  562.      You  may  enter  an  address  range  (hhhh kkkk), the address of
  563.      a single string (hhhh), or an address and  a  length  (hhhh  Ln)
  564.      on  each  line.  (Up  to 20 lines).  Upon receiving a blank line
  565.      as input, the program will  find  all  strings  terminated  with
  566.      a  $ starting at the first address in a range and continue find-
  567.      ing multiple strings to  the  second  address  if  present.   If
  568.      a  single  address  is  given  on a line a single string will be
  569.      read.  If a length is provided, the  string  will  be  truncated
  570.      to  that  length  or  at the terminator, which ever comes first.
  571.      (This is useful for data string which do not  have  $  terminat-
  572.      ors.)  Each string is displayed as it is found.  
  573.  
  574.           Following  this  the  program  reads through FILE.INT.  For
  575.      each "DOSCALL PRINT$  hhhh"  encountered  it  reads  the  string
  576.      from  FILE.COM  at  the  specified location (taking into account
  577.      the 100H byte program prefix) and prints that string as  a  com-
  578.      ment  next  to  the Macro.  Also, each time a register is loaded
  579.      with the address of a string,  that  string  is  shown  next  to
  580.      the code.  At the end of the file, UASM-INT will append a number
  581.      of EQUates and Data statements and define the  string  variables
  582.      with  names  Dhhhh.   Non-printing characters are converted into
  583.      hex bytes.  CR, LF, TAB, ESC, and $ are defined as symbols.
  584.  
  585.           DOSCALLs that do file I/O and  that  load  the  address  of
  586.      the  File  Control  Block  into  DX  will generate that FCB as a
  587.      string.   Any  address  which  is  used  within  brackets  (e.g.
  588.      LEA   DX,[hhhh]),  that  is  not already a known string address,
  589.      is assumed to be the address of a variable.   A  data  statement
  590.      is  generated  for  the  variable,  and  two bytes are extracted
  591.      from FILE.COM to show its initial value.
  592.  
  593.  
  594.  
  595.  
  596.  
  597.  
  598.  
  599.  
  600.  
  601.  
  602.  
  603.  
  604.  
  605.  
  606.  
  607.  
  608.  
  609.  
  610.  
  611.  
  612.  
  613.  
  614.  
  615.  
  616.                                                                          10
  617.  
  618.                  SAMPLE OUTPUT - Excerpts from DEBUG.STR
  619.  
  620. INCLUDE   UASM-DOS.MAC
  621. .RADIX    16 
  622.  
  623. START:  JMPS    L011D            
  624.  
  625. L011D:  MOV     SP,1822 
  626.         MOV     [1897],AL 
  627.         MOV     DX,0102 
  628.         MOV     AH,09 
  629.         INT     21 
  630.  
  631. DOSCALL PRINT$,D0102       ;CR,LF,'DEBUG-86  version 1.07',CR,LF,$ 
  632.         MOV     AX,2522 
  633.         MOV     DX,01E6 
  634.         INT     21 
  635.  
  636. DOSCALL SET$INT     01E6   ; Set interrupt vector (AL=INT, DS:DX=VECTOR)
  637.  
  638.         MOV     AL,23 
  639.         MOV     DX,01EB 
  640.         INT     21 
  641.  
  642. DOSCALL SET$INT     01EB   ; Set interrupt vector (AL=INT, DS:DX=VECTOR)
  643.  
  644.         MOV     DX,CS 
  645.         ADD     DX,01AB 
  646.         MOV     AH,26 
  647.         INT     21 
  648.  
  649. DOSCALL BUILD$PS    01AB      ; Create new program  segment  (DX=SEGMENT)
  650.  
  651.  
  652.         MOV     AX,DX 
  653.         MOV     DI,1832 
  654.         STOSW 
  655.         MOV     DX,0080 
  656.         MOV     AH,1A 
  657.         INT     21 
  658.  
  659. DOSCALL SET$DTA     0080      ; Set Disk Transfer Address to DX 
  660.  
  661.         MOV     AX,[0006] 
  662.         MOV     BX,AX 
  663.         CMP     AX,FFF0 
  664.         PUSH    CS 
  665.         POP     DS 
  666.         ADD     [0008],BX 
  667.         MOV     DI,005C 
  668.         MOV     SI,0081 
  669.         MOV     AX,2901 
  670.  
  671.  
  672.  
  673.  
  674.  
  675.  
  676.  
  677.  
  678.  
  679.  
  680.  
  681.  
  682.  
  683.  
  684.                                                                          11
  685.  
  686.         INT     21 
  687.  
  688. DOSCALL PARSE$         ; Parse Filespec (SI -> LINE, DI -> FCB, AL=CODE)
  689.  
  690.         CALL    L0917 
  691.         PUSH    CS 
  692.         POP     ES 
  693.         CMP     B,[005D],20 
  694.         JZ      L01B5 
  695.         JMPS    L01B5 
  696.  
  697. L01E3:  JMP     L04CB 
  698.  
  699. L01E6:   MOV      DX,167A             ;WARNING! This label not referenced
  700.         MOV     DS,AX 
  701.         MOV     SS,AX 
  702.         MOV     SP,1822 
  703.         MOV     AH,09 
  704.         INT     21 
  705.  
  706. DOSCALL PRINT$            ; Display string @DX till terminator 
  707.  
  708.         JMPS    L01B5 
  709.  
  710. L01FD:  MOV     AH,0A 
  711.         MOV     DX,1844 
  712.         INT     21 
  713.  
  714. DOSCALL INSTR$      1844  ; Input keyboard string (DX -> size,cnt,buffer)
  715.  
  716.         MOV     SI,1846 
  717. ;END CODE 
  718. .RADIX    16 
  719. CR   EQU  0D 
  720. LF   EQU  0A 
  721. TAB  EQU  09 
  722. ESC  EQU  1B 
  723. $    EQU  24 
  724. D167A     DB   CR,LF,'Program terminated normally',CR,LF,$ 
  725. D169A     DB   'Invalid drive or file name',CR,LF,$ 
  726. D16B7     DB   'File not found',CR,LF,$ 
  727. D16C8     DB   'No room in disk directory',CR,LF,$ 
  728. D16E4     DB   'Insufficient space on disk',CR,LF,$ 
  729. D1701     DB   'Disk$' 
  730. D1706     DB   'Write protect$' 
  731. D1714     DB   ' error reading drive A',CR,LF,$ 
  732. D172D     DB   'readwritInsufficient memory',CR,LF,$ 
  733. D174B     DB   '^ Error',CR,8A,' ',88,'Error in EXE/HEX file',CR,LF,$
  734. D176E     DB   'EXE/HEX file cannot be written',CR,LF,$ 
  735. D178F     DB   'Writing $' 
  736. D1798     DB   ' bytes',CR,LF,$ 
  737. D0102     DB   CR,LF,'DEBUG-86  version 1.07',CR,LF,$ 
  738.  
  739.  
  740.  
  741.  
  742.  
  743.  
  744.  
  745.  
  746.  
  747.  
  748.  
  749.  
  750.  
  751.  
  752. D1798     DB   ' bytes',CR,LF,$ 
  753. D0102     DB   CR,LF,'DEBUG-86  version 1.07',CR,LF,$ 
  754.  
  755.  
  756.  
  757.  
  758.  
  759.  
  760.  
  761.  
  762.  
  763.  
  764.  
  765.  
  766.  
  767.  
  768. D1798     DB   ' bytes',CR,LF,$ 
  769. D0102     DB   CR,LF,'DEBUG-86  version 1.07',CR,LF,$ 
  770.  
  771.  
  772.  
  773.  
  774.  
  775.  
  776.  
  777.  
  778.  
  779.  
  780.  
  781.  
  782.  
  783.